package main

import "fmt"

//Go语言中函数return不是原子操作，在底层是分为两步来执行
//1.返回值赋值
//defer
//2.真正的RET返回
//3.函数中，如果出现defer，那么defer执行的时机是在第一步和第二步之间
func f1() int {
	x := 5
	defer func() {
		x++ //修改的是x,不是返回值
		fmt.Printf("f1x=%d \n", x)
	}()
	fmt.Printf("f1=%d \n", x)
	return x //1.返回值赋值   2.defer     3.真正的ret
}

func f2() (x int) {
	defer func() {
		x++
		fmt.Printf("f2x=%d \n", x)
	}()
	fmt.Printf("f2=%d \n", x)
	return 5 //返回值=5
}

func f3() (y int) {
	x := 5
	defer func() {
		x++ //修改的是x
		fmt.Printf("f3x=%d \n", x)
	}()
	fmt.Printf("f3=%d \n", x)
	return x //y=x=5

}

func f4() (x int) {
	defer func(x int) {
		x++
		fmt.Printf("f4x=%d \n", x)
	}(x)
	fmt.Printf("f4=%d \n", x)
	return 5
}

func f5() (x int) {
	defer func(x int) int {
		x++
		fmt.Printf("f4x=%d \n", x)
		return x
	}(x)
	fmt.Printf("f4=%d \n", x)
	return 5
}
func main() {
	fmt.Println(f1())
	fmt.Println(f2())
	fmt.Println(f3())
	fmt.Println(f4())
	fmt.Println(f5())
}
